package pers.cz.orm.dao.dialect;

import pers.cz.common.exception.ErrorCode;
import pers.cz.common.exception.OrmException;
import pers.cz.orm.enums.DbConfigItem;
import utils.JefLog;
import utils.StringUtils;
import pers.cz.jefconfig.config.JefConfiguration;

import java.util.HashMap;
import java.util.Map;

/**
 * @program: jef-orm
 * @description: 抽象方言类
 * @author: Cheng Zhi
 * @create: 2023-08-12 18:21
 **/
public abstract class AbstractDialect implements DbDialect{

    private static JefLog jefLog = new JefLog(AbstractDialect.class);

    /**
     * 缓存所有实例化的Dialect,防止多次反射构建
     */
    public static ThreadLocal<Map<String, DbDialect>> dialectMap = new ThreadLocal<Map<String, DbDialect>>() {
        @Override
        protected Map<String, DbDialect> initialValue() {
            return new HashMap<String, DbDialect>();
        }
    };

    /**
     * 获取当前方言
     * @return
     */
    public static DbDialect getCurrentDbDialect(String url) {

        try {
            String dbType = StringUtils.split(url, ":")[1];
            DbDialect dbDialect = dialectMap.get().get(dbType);
            if (dbDialect != null) {
                return dbDialect;
            }

            if (dbType.toUpperCase().equals("MYSQL")) {
                JefConfiguration.set(DbConfigItem.MASTER_DB_DIALECT_NAME, "pers.cz.orm.dao.dialect.MysqlDialect");
            } else if (dbType.toUpperCase().equals("ORACLE")) {
                JefConfiguration.set(DbConfigItem.MASTER_DB_DIALECT_NAME, "pers.cz.orm.dao.dialect.OracleDialect");
            } else if (dbType.toUpperCase().equals("ANTDB")) {
                JefConfiguration.set(DbConfigItem.MASTER_DB_DIALECT_NAME, "pers.cz.orm.dao.dialect.AntDbDialect");
            } else if (dbType.toUpperCase().equals("POSTGRESQL")) {
                JefConfiguration.set(DbConfigItem.MASTER_DB_DIALECT_NAME, "pers.cz.orm.dao.dialect.PostgreSqlDialect");
            } else {
                throw new OrmException(ErrorCode.ORM_NO_DB_DISLECT_ERROR, dbType);
            }
            String diaLectName = JefConfiguration.get(DbConfigItem.MASTER_DB_DIALECT_NAME);
            Class<?> aClass = Class.forName(diaLectName);
            Object o = aClass.newInstance();
            return (DbDialect) o;
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            throw new OrmException(ErrorCode.ORM_GET_DB_DISLECT_ERROR);
        }

    }
}
